package tool.code.generater.util;

import com.alibaba.druid.util.StringUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class CommonUtil {
    private static final String workDir = System.getProperty("user.dir");

    public static ObjectNode fromFile(String fileName) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(JsonReadFeature.ALLOW_TRAILING_COMMA.mappedFeature());
        mapper.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
        try {
            String content = ignoreLineAnnotation(fileName);
            JsonNode jsonNode = mapper.readTree(content);
            if (jsonNode.isObject()) {
                return (ObjectNode) jsonNode;
            }
            throw new IllegalArgumentException("文件中的内容不为jsonObject");
        } catch (IOException e) {
            throw new RuntimeException("json文件读取报错", e);
        }
    }
    public static String toJsonStringPretty(Object obj) {
        ObjectMapper mapper = new ObjectMapper();
//        mapper.enable(JsonParser.Feature.ALLOW_COMMENTS);
//        mapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);
//        mapper.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
//        mapper.enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature());
        try {
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (IOException e) {
            throw new RuntimeException("json对象转字符串报错", e);
        }
    }
    public static <T> T fromFileToObject(String fileName, Class<T> clazz) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(JsonReadFeature.ALLOW_TRAILING_COMMA.mappedFeature());
        mapper.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
        try {
            String content = ignoreLineAnnotation(fileName);
            T obj = mapper.readValue(content, clazz);
            if (Objects.nonNull(obj)) {
                return obj;
            }
            throw new IllegalArgumentException("文件内容未能正确转换为对象");
        } catch (IOException e) {
            throw new RuntimeException("json文件读取报错", e);
        }
    }
    public static <T> T fromJsonToObject(String jsonString, Class<T> clazz) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(JsonReadFeature.ALLOW_TRAILING_COMMA.mappedFeature());
        mapper.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
        mapper.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
        mapper.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        try {
            T obj = mapper.readValue(jsonString, clazz);
            if (Objects.nonNull(obj)) {
                return obj;
            }
            throw new IllegalArgumentException("JSON字符串未能正确转换为对象");
        } catch (IOException e) {
            throw new RuntimeException("JSON解析报错", e);
        }
    }
    public static String dereference(String s, Map<String, String> scope) {
        if (Objects.isNull(scope) || StringUtils.isEmpty(s)) {
            return s;
        }
        for (Map.Entry<String, String> entry : scope.entrySet()) {
            s = s.replace(String.format("${%s}", entry.getKey()), entry.getValue());
        }
        return s;
    }

    public static String ignoreLineAnnotation(String filename) throws IOException {
        File file = new File(workDir, filename);
        if (!file.exists()) {
            file = new File(filename);
        }
        List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
        StringBuilder result = new StringBuilder();
        for (String line : lines) {
            if (!StringUtils.isEmpty(line)) {
                if (line.trim().startsWith("//")) {
                    continue;
                }
                result.append(line.trim());
            }
        }
        return result.toString();
    }

    public static String preprocessPath(String path) {
        if (StringUtils.isEmpty(path)) {
            return path;
        }
        //判断路径是填写的绝对路径，还是相对路径
        Path pathObj = Paths.get(path);
        if (!pathObj.isAbsolute()) {
            return Paths.get(workDir, path).toString();
        }
        return path;
    }

    public static String extractBasePackage(String path) {
        if (StringUtils.isEmpty(path)) {
            return path;
        }
        String fixedStr = "\\src\\main\\java\\";
        int i = path.lastIndexOf(fixedStr);
        i = i == -1 ? 0 : i + fixedStr.length();
        String packagePath = path.substring(i);
        String s = packagePath.replaceAll("\\\\", "\\.");
        if (s.startsWith(".")) {
            s = s.substring(1);
        }
        if (s.endsWith(".")) {
            s = s.substring(0, s.length() - 1);
        }
        return s;
    }

    public static String joinPackage(String... packages) {
        return String.join(".", packages);
    }
}
